package com.gokzzz.service.impl;

import com.alibaba.fastjson.JSON;
import com.gokzzz.entity.Article;
import com.gokzzz.mapper.ArticleMapper;
import com.gokzzz.mq.index.ArticleMqIndexMessage;
import com.gokzzz.repository.EsRepository;
import com.gokzzz.response.PageData;
import com.gokzzz.service.EsService;
import lombok.RequiredArgsConstructor;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ganfujia
 * @date 2022/5/20 11:08
 */
@Service
@RequiredArgsConstructor
public class EsServiceImpl implements EsService {

    private final EsRepository esRepository;
    private final ArticleMapper articleMapper;
    private final RestHighLevelClient restHighLevelClient;


    /**
     * 分页查询
     *
     * @param current 当前页
     * @param size    页数
     * @param q       条件
     * @return 记录
     */
    @Override
    public PageData<Article> page(Long current, Long size, String q) throws IOException {
        SearchRequest searchRequest = new SearchRequest("article");
        SearchSourceBuilder sourceBuilder = new SearchSourceBuilder();
        sourceBuilder.query(QueryBuilders.matchQuery("title", q))
                .from((int) ((current - 1) * size))
                .size(Math.toIntExact(size));
        searchRequest.source(sourceBuilder);
        SearchResponse search = restHighLevelClient.search(searchRequest, RequestOptions.DEFAULT);
        SearchHit[] hits = search.getHits().getHits();
        ArrayList<Article> articles = new ArrayList<>();
        for (SearchHit hit : hits) {
            Article article = JSON.parseObject(hit.getSourceAsString(), Article.class);
            articles.add(article);
        }
        return new PageData<>(current, size, (long) articles.size(), articles);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void initData() {
        esRepository.deleteAll();
        List<Article> articles = articleMapper.selectList(null);
        esRepository.saveAll(articles);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createOrUpdateIndex(ArticleMqIndexMessage message) {
        Article article = articleMapper.selectById(message.getArticleId());
        if (ArticleMqIndexMessage.CREATE.equals(message.getType())) {
            esRepository.save(article);
        }else {
            removeIndex(message);
            esRepository.save(article);
        }

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeIndex(ArticleMqIndexMessage message) {
        Long articleId = message.getArticleId();
        esRepository.deleteById(articleId);
    }
}
